#include "stdafx.h"
#include "ManagedCryptBlob.h"

using namespace System;

namespace Safe
{
	ManagedCryptBlob::ManagedCryptBlob(CRYPT_DER_BLOB &pBlob) { 
		this->Data = gcnew array<unsigned char>( pBlob.cbData );
		System::Runtime::InteropServices::Marshal::Copy( (IntPtr)(pBlob.pbData), this->Data, 0, pBlob.cbData );
	}

	ManagedCryptBlob::ManagedCryptBlob(BYTE* pbData, DWORD cbData) { 
		this->Data = gcnew array<unsigned char>( cbData );
		System::Runtime::InteropServices::Marshal::Copy( (IntPtr)(pbData), this->Data, 0, cbData );
	}

	ManagedCryptBlob::ManagedCryptBlob(array<unsigned char>^ arrData) {
		this->Data = gcnew array<unsigned char>( arrData->Length );
		System::Array::Copy( arrData, this->Data, arrData->Length );
	}

	ManagedCryptBlob::~ManagedCryptBlob() { 
		// do nothing
	}	


	/// Copies the data from the ManagedCryptBlob into the structure.  To get 
	/// the length of the buffer needed to hold the data, either use the 
	/// Length property of the object, or call this function with a CRYPT_DER_BLOB
	/// that has NULL for the pbData member.  This will populate the cbData member
	/// with the required length.
	/// This function does not perform allocation, so the calling function is
	/// responsible for freeing the CRYPT_DER_BLOB's pbData buffer.
	bool ManagedCryptBlob::CreateBlob(CRYPT_DER_BLOB &blob) {
		if( blob.pbData == NULL ) {
			blob.cbData = this->Length;
			return true;
		}
		if( blob.cbData != this->Length ) { 
			return false;
		} else { 
			System::Runtime::InteropServices::Marshal::Copy( this->Data, 0, (IntPtr)(blob.pbData), this->Length );
			return true;
		}
	}


	/// Determines if this object is equivalent to another ManagedCryptBlob.  If
	/// the lengths of the buffers differ, or if any of the data within the buffers
	/// differ, the function returns false.  Otherwise, the objects are
	/// considered equal.
	bool ManagedCryptBlob::Equals( ManagedCryptBlob^ obj ) { 
		if( this->Length == obj->Length ) { 
			for( int i=0; i<Length; i++ ) { 
				if( this->Data[i] != obj->Data[i] ) { 
					return false;
				}
			}
			return true;
		} else { 
			return false;
		}
	}

	
}